using UnityEngine;
using System;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

[Serializable]
public class NamedObject
{
    /// <summary>全局访问用的唯一 Key</summary>
    public string key;

    /// <summary>
    /// 可拖 Prefab / ScriptableObject / MonoScript（脚本文件）/ 组件实例……
    /// </summary>
    public UnityEngine.Object asset;
}

public class ObjectManager : MonoBehaviour
{
    public static ObjectManager Instance { get; private set; }

    [Header("在这里拖一组全局对象 / 脚本")]
    [SerializeField]
    private List<NamedObject> objects = new List<NamedObject>();

    // 运行时的查表：可能存 Prefab、SO，或者 Auto-Create 的组件实例
    private Dictionary<string, UnityEngine.Object> dict = new Dictionary<string, UnityEngine.Object>();

    void Awake()
    {
        // 单例
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);

        // 用于挂自动创建的组件
        var autoRoot = new GameObject("_AutoComponents");
        autoRoot.transform.SetParent(transform);

        // 初始化字典
        foreach (var no in objects)
        {
            if (string.IsNullOrEmpty(no.key))
            {
                Debug.LogWarning("ObjectManager: 存在空 key，已跳过");
                continue;
            }
            if (dict.ContainsKey(no.key))
            {
                Debug.LogWarning($"ObjectManager: 重复的 key “{no.key}”，已跳过后续同名项");
                continue;
            }

            var asset = no.asset;
            if (asset == null)
            {
                Debug.LogWarning($"ObjectManager: key “{no.key}” 的 asset 为空");
                continue;
            }

            // —— 如果拖的是脚本文件（MonoScript），就自动挂到 GameObject —— 
    #if UNITY_EDITOR
            if (asset is MonoScript ms)
            {
                var type = ms.GetClass();
                if (type != null && typeof(MonoBehaviour).IsAssignableFrom(type))
                {
                    // 新建一个空物体，Attach 脚本
                    var go = new GameObject($"{no.key}_Auto");
                    go.transform.SetParent(autoRoot.transform);
                    var comp = go.AddComponent(type) as Component;
                    dict.Add(no.key, comp);
                    continue;
                }
                else
                {
                    Debug.LogWarning($"ObjectManager: key “{no.key}” 对应脚本类型不是 MonoBehaviour");
                    continue;
                }
            }
    #endif

            // —— 否则按原来逻辑直接存 asset —— 
            dict.Add(no.key, asset);
        }
    }

    /// <summary>
    /// 获取你要的资源／组件
    /// </summary>
    /// <typeparam name="T">比如 GameObject / ScriptableObject / 你的自定义 MonoBehaviour</typeparam>
    public T Get<T>(string key) where T : UnityEngine.Object
    {
        if (dict.TryGetValue(key, out var obj) && obj is T t)
            return t;

        Debug.LogError($"ObjectManager: 找不到 key “{key}” 或类型不匹配（期望 {typeof(T).Name}）");
        return null;
    }

    /// <summary>
    /// 运行时动态添加新的全局对象（不序列化）
    /// </summary>
    public void Add(string key, UnityEngine.Object obj)
    {
        dict[key] = obj;
    }

    /// <summary>
    /// 删除
    /// </summary>
    public bool Remove(string key)
    {
        return dict.Remove(key);
    }
}